package com.handydata.antifraud.ws.dap;

import io.netty.util.internal.StringUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.PostConstruct;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.handydata.antifraud.annotation.Comment;
import com.handydata.antifraud.common.constant.DataSourceCode;
import com.handydata.antifraud.common.exception.WsInvokeException;
import com.handydata.antifraud.to.dap.GpsShipReqTO;
import com.handydata.antifraud.to.dap.GpsShipResTO;
import com.handydata.antifraud.util.DateUtil;
import com.handydata.antifraud.ws.WsInvocationService;

/**
 * GPS归属地查询
 *
 */
@Slf4j
@Service("gpsShipWsService")
@Comment("百度GPS转位置API")
public class GpsShipWsServiceImpl extends DataPlatformWsService<GpsShipReqTO, GpsShipResTO>
		implements WsInvocationService<GpsShipReqTO, GpsShipResTO> {

	@Override
	public GpsShipResTO query(GpsShipReqTO req) throws WsInvokeException {
		log.info("百度GPS转位置API请求参数 {}", req);
		GpsShipResTO resTO = new GpsShipResTO();
		if (StringUtil.isNullOrEmpty(req.getLongitudeAndLatitude()) && 
			StringUtil.isNullOrEmpty(req.getBdLongitudeAndLatitude())){
			resTO.setResCode("1111");
			resTO.setResMsg("百度GPS转位置API接口经纬度参数为空");
			return resTO;
		}
		if (!StringUtil.isNullOrEmpty(req.getLongitudeAndLatitude())) {
			JSONObject resData = JSONObject.parseObject(req.getLongitudeAndLatitude());
			String wgLat = resData.getString("wgLat");
			String wgLon = resData.getString("wgLon");
			if (!StringUtil.isNullOrEmpty(wgLat) && Double.parseDouble(wgLat) != 0.0 &&
				!StringUtil.isNullOrEmpty(wgLon) && Double.parseDouble(wgLon) != 0.0){
				req.setXmlType("1");
			} else if (!StringUtil.isNullOrEmpty(req.getBdLongitudeAndLatitude())) {
				JSONObject resBdData = JSONObject.parseObject(req.getBdLongitudeAndLatitude());
				String bDwgLat = resBdData.getString("wgLat");
				String bDwgLon = resBdData.getString("wgLon");
				if (!StringUtil.isNullOrEmpty(bDwgLat) && Double.parseDouble(bDwgLat) != 0.0 &&
					!StringUtil.isNullOrEmpty(bDwgLon) && Double.parseDouble(bDwgLon) != 0.0){
					req.setLongitudeAndLatitude(req.getBdLongitudeAndLatitude());
					req.setXmlType("1");
				} else {
					resTO.setResCode("1111");
					resTO.setResMsg("百度GPS转位置API接口经纬度参数为空");
					return resTO;
				}
			} else {
				resTO.setResCode("1111");
				resTO.setResMsg("百度GPS转位置API接口经纬度参数为空");
				return resTO;
			}
		} else {
			if (!StringUtil.isNullOrEmpty(req.getBdLongitudeAndLatitude())) {
				JSONObject resBdData = JSONObject.parseObject(req.getBdLongitudeAndLatitude());
				String bDwgLat = resBdData.getString("wgLat");
				String bDwgLon = resBdData.getString("wgLon");
				if (!StringUtil.isNullOrEmpty(bDwgLat) && Double.parseDouble(bDwgLat) != 0.0 &&
					!StringUtil.isNullOrEmpty(bDwgLon) && Double.parseDouble(bDwgLon) != 0.0){
					req.setLongitudeAndLatitude(req.getBdLongitudeAndLatitude());
					req.setXmlType("1");
				} else {
					resTO.setResCode("1111");
					resTO.setResMsg("百度GPS转位置API接口经纬度参数为空");
					return resTO;
				}
			}
		}	
		this.dataType = DataSourceCode.GPS_SHIP.getCode();
		resTO = executeQuery(req);
		// 行内压测挡板处理
//		try {
//			Thread.sleep(250);
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
//		resTO.setGpsCity("安徽");
//		resTO.setGpsProvince("六安");
//		resTO.setAreaOfGPS("安徽六安");
//		resTO.setResCode("0000");
//		resTO.setResMsg("查询成功");
//		// 挡板入库
//		DataCallLogsReqBO dataCallLogsReqBO = new DataCallLogsReqBO();
//		dataCallLogsReqBO.setId(UUID.randomUUID().toString().replace("-", ""));
//		dataCallLogsReqBO.setParams(JSONObject.toJSONString(req));
//		dataCallLogsReqBO.setElapsed(250);
//		dataCallLogsReqBO.setWselapsed(250);
//		dataCallLogsReqBO.setDataType(this.dataType);
//		dataCallLogsReqBO.setResCode("0000");
//		dataCallLogsReqBO.setResMsg("查询成功");
//		dataCallLogsReqBO.setResult("安徽六安");
//		dataCallLogsReqBO.setOrderId(req.getOrderId());
//		dataCallLogsReqBO.setUpdateTime(new Date());
//		dataCallLogsReqBO.setCreateTime(new Date());
//		dataCallLogsService.createDataCallLogs(dataCallLogsReqBO);
		return resTO;
	}
	
	@Override
	protected String createQueryXml(GpsShipReqTO req) {
		StringBuilder xml = new StringBuilder();
		if("1".equals(req.getXmlType())) {
	        JSONObject jo = JSONObject.parseObject(req.getLongitudeAndLatitude());
	        xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
	        xml.append("<subatm>");
	        xml.append("<application>GwBiz.Req</application>");
	        xml.append("<version>1.0.0</version>");
	        xml.append("<sendTime>").append(DateUtil.now14()).append("</sendTime>");
	        xml.append("<transCode>100080</transCode>");
	        xml.append("<channelId>").append(encryInfo.getChannelId()).append("</channelId>");
	        xml.append("<channelOrderId>").append(DateUtil.now17()).append("</channelOrderId>");
	        xml.append("<location>").append(jo.getString("wgLon")).append(",").append(jo.getString("wgLat")).append("</location>");
	        xml.append("</subatm>");
        }else {
        	xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
            xml.append("<subatm>");
            xml.append("<application>GwBiz.Req</application>");
            xml.append("<version>1.0.0</version>");
            xml.append("<sendTime>").append(DateUtil.now14()).append("</sendTime>");
            xml.append("<transCode>100075</transCode>");
            xml.append("<channelId>").append(encryInfo.getChannelId()).append("</channelId>");
            xml.append("<channelOrderId>").append(DateUtil.now17()).append("</channelOrderId>");
            xml.append("<phone>").append(req.getPhoneNum()).append("</phone>");
            xml.append("</subatm>");
        }
		req.setQueryXml(xml.toString());
		return xml.toString();
	}
	
	@Override
	protected GpsShipResTO parseResultAndSave(String resultXml, String orderId, Date createDate) {
		log.info("调用GPS归属地查询接口返回报文：{}", resultXml);
		GpsShipResTO resTO = new GpsShipResTO();
		try {
			// 解析xml，保存本地DB
			JSONObject jasonObject = JSONObject.parseObject(resultXml);
			if (null != jasonObject) {
				if ("0000".equals(jasonObject.get("resCode"))) {
					JSONObject resData = (JSONObject) jasonObject.get("resData");
					if (!StringUtil.isNullOrEmpty(resData.getString("location"))) {
						resTO.setAreaOfGPS(resData.getString("formatted_address"));
						resTO.setGpsLocation(resData.getString("location"));
						JSONObject addressComponent = (JSONObject) resData.get("addressComponent");
						resTO.setGpsProvince(addressComponent.getString("province"));
						resTO.setGpsCity(addressComponent.getString("city"));
					} else if (resData.getString("area")!=null&&(resData.getString("area").contains("上海市") || resData.getString("area").contains("北京市") ||
							resData.getString("area").contains("天津市") || resData.getString("area").contains("重庆市"))) {
						String aa1 = resData.getString("area").substring(0, 2);
						resTO.setGpsCity(aa1);
						resTO.setGpsProvince(aa1);
						resTO.setAreaOfGPS(resData.getString("area"));
					} else if (resData.containsKey("company")) {
						resTO.setGpsCity(resData.getString("city"));
						resTO.setGpsProvince(resData.getString("province"));
						resTO.setAreaOfGPS(resData.getString("province") + resData.getString("city"));
					} else {
						Map<String,String> result = addressResolution(resData.getString("area"));
						resTO.setGpsCity(result != null ? result.get("city") : "");
						resTO.setGpsProvince(result != null ? result.get("province") : "");
						resTO.setAreaOfGPS(resData.getString("area"));
					}
				}	
				resTO.setResCode((String)jasonObject.get("resCode"));
				resTO.setResMsg((String)jasonObject.get("resMsg"));
			} else {
				resTO.setResCode("1111");
				resTO.setResMsg("GPS归属地查询接口返回数据异常");
			}
		} catch (Exception e) {
			log.info("调用GPS归属地查询接口异常：{}", e);
			resTO.setResCode("1111");
			resTO.setResMsg("调用GPS归属地查询接口异常");
		}
		log.info("调用GPS归属地查询接口返回结果：{}", JSONObject.toJSONString(resTO));
		return resTO;
	}
	
	@SuppressWarnings("unchecked")
	@PostConstruct
	@Override
	public void register() {
		registerToWsServiceFactory(this, GpsShipReqTO.class);
	}
	
	public static void main(String[] args) {
		String aa = "{\"resCode\":\"0000\",\"resMsg\":\"查询成功\",\"resData\":{\"area\":\"上海市浦东新区\",\"sex\":\"男\",\"birthday\":\"1986年09月09日\",\"verify\":\"\"}}";
		JSONObject jasonObject = JSONObject.parseObject(aa);
		System.out.println("==============" + jasonObject);
		JSONObject areaJson = jasonObject.getJSONObject("resData");
		System.out.println("==============" + areaJson);
		if (areaJson.getString("area").contains("上海市") || areaJson.getString("area").contains("北京市") ||
			areaJson.getString("area").contains("天津市") || areaJson.getString("area").contains("重庆市")) {
			String aa1 = areaJson.getString("area").substring(0, 2);
			System.out.println("==============" + aa1);
		}
		Map<String,String> result = addressResolution("内蒙古自治区赤峰市敖棋阿");
		System.out.println("==============" + result);
	}
	
	/**
     * 解析地址
     * @param address
     * @return
     */
    private static Map<String,String> addressResolution(String address){
		String regex = "(?<province>[^省]+省|.+自治区)(?<city>[^市]+市|.+自治州)(?<county>[^县]+县|.+区)?(?<town>[^区]+区|.+镇)?(?<village>.*)";
		Matcher m = Pattern.compile(regex).matcher(address);
		String province;
		String city;
		String county;
		String town;
		String village;
		List<Map<String, String>> table = new ArrayList<>();
		Map<String, String> row = null;
		while (m.find()) {
            row= new LinkedHashMap<>();
            province=m.group("province");
            row.put("province", province==null?"":province.trim());
            city=m.group("city");
            row.put("city", city==null?"":city.trim());
            county=m.group("county");
            row.put("county", county==null?"":county.trim());
            town=m.group("town");
            row.put("town", town==null?"":town.trim());
            village=m.group("village");
            row.put("village", village==null?"":village.trim());
            table.add(row);
        }
        return row;
    }

}